package com.zhang.system.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhang.common.chart.PieChartData;
import com.zhang.common.exception.myexception.StateException;
import com.zhang.common.util.md5.Md5Util;
import com.zhang.common.util.redis.RedisUtil;
import com.zhang.common.util.result.R;
import com.zhang.common.util.result.RUtils;
import com.zhang.common.util.time.TimeUtils;
import com.zhang.system.entity.Role;
import com.zhang.system.entity.UserRole;
import com.zhang.system.service.IRoleService;
import com.zhang.system.service.IUserRoleService;

import com.zhang.system.config.UserConfig;
import com.zhang.system.entity.AdminUser;
import com.zhang.system.entity.UserInfoVo;
import com.zhang.system.entity.UserSearch;
import com.zhang.system.mapper.AdminUserMapper;
import com.zhang.system.service.IAdminUserService;
import com.zhang.system.vo.AdminUserCompositionStatisticVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统用户表 服务实现类
 * </p>
 *
 * @author 战神
 * @since 2023-07-02
 */
@Service
@Slf4j
public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser> implements IAdminUserService {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private IUserRoleService userRoleServicee;
    @Autowired
    private IRoleService roleService;

    /**
     * 管理员用户登录
     *
     * @param key      登录的密钥
     * @param password 密码
     * @param type     登录密钥类型：id,phone,sms,username,email
     * @return {@link R}
     */
    @Override
    public R adminUserLogin(Object key, String password, String type) {
        AdminUser adminUser = queryUserByCondition(key, type);
        if (adminUser != null) {
            String pass = password + adminUser.getMd5Salt();
            String md5 = Md5Util.getMD5(pass);
            String adminUserPassword = adminUser.getPassword();
            if (adminUser.getState() != 0) {
                log.error("该用户被禁用");
                throw new StateException("用户");
            }
            if (md5.equals(adminUserPassword)) {
                /*登录返回*/
                StpUtil.login(adminUser.getId());
                HashMap<String, String> map = new HashMap<>();
                map.put("token", StpUtil.getTokenValue());
                /*设置当前登录时间*/
                UpdateWrapper<AdminUser> wrapper = new UpdateWrapper<>();
                wrapper.eq("id", adminUser.getId())
                        .set("last_login_time", TimeUtils.getLocalDateTimeStr());
                baseMapper.update(null, wrapper);
                return RUtils.successDataMsg(map, "登录成功");
            } else {
                return RUtils.err(401, "密码错误");
            }
        }
        return RUtils.err(401, "用户不存在");
    }


    @Override
    public AdminUser getUserInfo(Long userId) {
        AdminUser adminUser = baseMapper.getAdminUserInfo(userId);
        return adminUser;
    }

    /**
     * 添加后台人员
     *
     * @param user 用户
     * @return {@link R}
     */
    @Override
    public R addAdminUser(AdminUser user) {
        long id = StpUtil.getLoginIdAsLong();
        AdminUser adminUser = queryUserByCondition(id, UserConfig.ID);
        user.setCreateBy(adminUser.getUserName());
        Map<String, String> md5 = Md5Util.getMD5Slat(user.getPassword());
        user.setMd5Salt(md5.get("slat"));
        user.setPassword(md5.get("value"));
        String timeStr = TimeUtils.getLocalDateTimeStr();
        user.setCreateTime(timeStr);
        baseMapper.insert(user);
        /*角色插入*/
        ArrayList<UserRole> userRoles = new ArrayList<>();
        for (Long roleId : user.getRoleIds()) {
            userRoles.add(new UserRole(user.getId(), roleId));
        }
        userRoleServicee.saveBatch(userRoles);
        return RUtils.successMsg("新增成功");
    }

    /**
     * 自定义条件查询用户
     *
     * @param key  关键
     * @param type 查询条件：id,phone,sms,username,email
     * @return {@link AdminUser}
     */
    public AdminUser queryUserByCondition(Object key, String type) {
        AdminUser adminUser = null;
        QueryWrapper<AdminUser> wrapper = new QueryWrapper<>();
        switch (type) {
            case UserConfig.ID:
                //使用id登录
                adminUser = baseMapper.selectById(Long.valueOf(String.valueOf(key)));
                break;
            case UserConfig.EMAIL:
                //使用邮箱登录
                wrapper.eq("email", key);
                adminUser = baseMapper.selectOne(wrapper);
                break;
            case UserConfig.PHONE:
                //使用手机号登录
                wrapper.eq("phone", key);
                adminUser = baseMapper.selectOne(wrapper);
                break;
            case UserConfig.USER_NAME:
                //使用用户名登录
                wrapper.eq("user_name", key);
                adminUser = baseMapper.selectOne(wrapper);
                break;
            case UserConfig.SMS:
                //使用短信登录
                break;
        }
        return adminUser;
    }

    @Override
    public UserInfoVo getUserInfVo(Long userId) {
        /*判断缓存中是否存在*/
        Map<Object, Object> hmget = redisUtil.hmget("UserVo:" + userId);
        if (MapUtil.isNotEmpty(hmget)) {
            return new ObjectMapper().convertValue(hmget, UserInfoVo.class);
        } else {
            AdminUser adminUserInfo = baseMapper.getAdminUserInfo(userId);
            UserInfoVo userInfoVo = new UserInfoVo();
            userInfoVo.setUserId(adminUserInfo.getId());
            /*属性拷贝*/
            BeanUtils.copyProperties(adminUserInfo, userInfoVo);
            /*写入缓存中*/
            redisUtil.hObjectSet("UserVo:" + userId, userInfoVo, 3600L);
            return userInfoVo;
        }
    }

    @Override
    public List<AdminUser> userSeach(UserSearch userSearch) {
        List<AdminUser> adminUsers = baseMapper.userSeach(userSearch);
        return adminUsers;
    }

    @Override
    public boolean isAdmin(Long adminUserId) {
        List<Role> userRoleInfo = userRoleServicee.getUserRoleInfo(adminUserId);
        if (userRoleInfo.size() > 0) {
            Role role = userRoleInfo.get(0);
            if ("admin".equals(role.getRoleKey())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public R updateAdminUser(AdminUser adminUser) {
        if (isAdmin(adminUser.getId())) {
            /*不能被修改的信息*/
            adminUser.setUserName(null);
            adminUser.setRoleIds(null);
            adminUser.setState(null);
            adminUser.setPassword(null);
        }
        /*重置密码*/
        if (adminUser.getPassword()!=null){
            Map<String, String> md5 = Md5Util.getMD5Slat(adminUser.getPassword());
            adminUser.setMd5Salt(md5.get("slat"));
            adminUser.setPassword(md5.get("value"));
        }
        boolean b = updateById(adminUser);
        /*角色关联表更新*/
        ArrayList<UserRole> userRoles = new ArrayList<>();
        if (adminUser.getRoleIds()!=null){
            for (Long roleId : adminUser.getRoleIds()) {
                userRoles.add(new UserRole(adminUser.getId(), roleId));
            }
            userRoleServicee.saveBatch(userRoles);
        }
        return b ? RUtils.successMsg("修改成功") : RUtils.err("修改失败");
    }
    @Override
    public List<AdminUser> getUserListFromRoleKeys(List<String> roleKeys) {
        /*第一步查询角色的id*/
        QueryWrapper<Role> roleWrapper = new QueryWrapper<>();
        roleWrapper.in("role_key",roleKeys);
        List<Role> roleList = roleService.list(roleWrapper);
        List<Long> roleIds = roleList.stream().map(Role::getId).collect(Collectors.toList());
        /*第二步，查询关联表，获取这些角色对应的用户id*/
        List<UserRole> userRoleList = userRoleServicee.list(new QueryWrapper<UserRole>().in("role_id", roleIds));
        List<Long> userIds = userRoleList.stream().map(UserRole::getUserId).collect(Collectors.toList());
        /*第三步：查询用户信息*/
        List<AdminUser> list = listByIds(userIds);
        return list;
    }

    @Override
    public AdminUserCompositionStatisticVO UserCompositionStatistic() {
        AdminUserCompositionStatisticVO vo = new AdminUserCompositionStatisticVO();
        List<PieChartData> pieChartData = baseMapper.userGenderStatistic();
        vo.setGenderData(pieChartData);
        return vo;
    }
}
